package mybatis.interceptor;

import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.cache.CacheKey;
import org.apache.ibatis.executor.Executor;
import org.apache.ibatis.mapping.BoundSql;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.plugin.*;
import org.apache.ibatis.session.ResultHandler;
import org.apache.ibatis.session.RowBounds;

import java.util.Map;
import java.util.Properties;

@Intercepts(value = {
        @Signature(type = Executor.class, method = "query",
                args = {MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class, CacheKey.class, BoundSql.class}),
        @Signature(type = Executor.class, method = "query",
                args = {MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class}
        ),
        @Signature(type = Executor.class, method = "update",
                args = {MappedStatement.class, Object.class})
}
)
@Slf4j
@Data
public class SqlPrintForPlusInteceptor implements Interceptor {
    private Object target;
    // deal with added wrapper ,

    @Override
    public Object intercept(Invocation invocation) throws Throwable {
        Object[] args = invocation.getArgs();
        MappedStatement ms = (MappedStatement) args[0];
        BoundSql boundSql;
        Object parameter = args[1];
        // get method
        String methodName = invocation.getMethod().getName();
        if(methodName.equals("update")){
            boundSql = ms.getBoundSql(parameter);
            log.info("current run sql is {}",boundSql.getSql());
            if(parameter!=null){
                if(parameter instanceof Map){
                    log.info("paramter is {}",(Map)parameter);
                }else{
                    log.info("paramter is {}",parameter);
                }
            }


        }else{
            //由于逻辑关系，只会进入一次
            if (args.length == 4) {
                //4 个参数时
                boundSql = ms.getBoundSql(parameter);
            } else {
                //6 个参数时
                boundSql = (BoundSql) args[5];
            }
            // Caused by: java.lang.NullPointerException? when use
            if(parameter!=null){
                log.info("sql:{},{}",boundSql.getSql(),parameter.toString());
            }else{
                log.info("sql:{}",boundSql.getSql());

            }
        }

        return invocation.proceed();
    }

    @Override
    public Object plugin(Object target) {
        this.target = target;
        return Plugin.wrap(target, this);
    }


    @Override
    public void setProperties(Properties properties) {

    }
}